package com.linkoog.devtools.websocket.wsclient.jdk;

import com.linkoog.devtools.websocket.wsclient.WSClient;
import org.apache.commons.lang3.StringUtils;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.WebSocket;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;
import java.util.stream.Collectors;

public class JdkWSClient implements WSClient {

    private ExecutorService executor;
    private HttpClient httpClient;
    private WebSocket webSocket;


    public boolean connect(String url,Map<String, String> cookies, Map<String, String> headers, WebSocket.Listener listener){
        try {
            executor = Executors.newFixedThreadPool(3);
            httpClient = HttpClient.newBuilder().executor(executor).build();
            WebSocket.Builder builder = httpClient.newWebSocketBuilder();
            if (cookies != null && !cookies.isEmpty()){
                String cookieString = cookies.entrySet().stream()
                        .filter(entry -> entry.getKey() != null && entry.getValue() != null)
                        .map(entry -> entry.getKey() + "=" + entry.getValue())
                        .collect(Collectors.joining("; "));

                if (StringUtils.isNotBlank(cookieString)){
                    builder.header("Cookie", cookieString);
                }
            }
            if (headers != null && !headers.isEmpty()){
                headers.entrySet().stream()
                        .filter(entry -> StringUtils.isNotBlank(entry.getKey()) && entry.getValue() != null)
                        .forEach(entry -> builder.header(entry.getKey(), entry.getValue()));
            }
            webSocket = builder
                    .buildAsync(URI.create(url), listener)
                    .join();
            return webSocket != null;
        }catch (Throwable throwable){
        }
        return false;
    }

    public void send(String message){
        if (webSocket != null && !webSocket.isOutputClosed()){
            webSocket.sendText(message, true).join();
        }
    }

    public void close(){
        try {
            if (webSocket != null && !webSocket.isOutputClosed()){
                webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok").join();
            }
            executor.shutdown();
        }catch (Throwable throwable){
        }
    }


}
